安装配置 HAProxy 1.8.8

文档

http://cbonte.github.io/haproxy-dconv/

http://www.haproxy.org

下载安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

## 源码地址:http://www.haproxy.org/#down

wget https://www.haproxy.org/download/1.8/src/haproxy-1.8.8.tar.gz

## 安装依赖包

yum -y install gcc
yum -y install pcre pcre-static pcre-devel openssl openssl-devel zlib zlib-devel

## haproxy 语法检测支持包
yum -y install psmisc

## 编译安装

tar -xzvf haproxy-1.8.8.tar.gz
cd haproxy-1.8.8

## 可选其它参数 USE_CRYPT_H=1 USE_LIBCRYPT=1
make PREFIX=/usr/local/haproxy TARGET=linux2628 USE_STATIC_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1

make install PREFIX=/usr/local/haproxy

cp -R ./examples/errorfiles /usr/local/haproxy
编译参数说明:
TARGET 参数 :

    - linux22     for Linux 2.2
    - linux24     for Linux 2.4 and above (default)
    - linux24e    for Linux 2.4 with support for a working epoll (> 0.21)
    - linux26     for Linux 2.6 and above
    - linux2628   for Linux 2.6.28, 3.x, and above (enables splice and tproxy)
    - solaris     for Solaris 8 or 10 (others untested)
    - freebsd     for FreeBSD 5 to 10 (others untested)
    - netbsd      for NetBSD
    - osx         for Mac OS/X
    - openbsd     for OpenBSD 5.7 and above
    - aix51       for AIX 5.1
    - aix52       for AIX 5.2
    - cygwin      for Cygwin
    - haiku       for Haiku
    - generic     for any other OS or version.
    - custom      to manually adjust every setting

CPU 参数:

    - i686 for intel PentiumPro, Pentium 2 and above, AMD Athlon
    - i586 for intel Pentium, AMD K6, VIA C3.
    - ultrasparc : Sun UltraSparc I/II/III/IV processor
    - native : use the build machine's specific processor optimizations. Use with
        extreme care, and never in virtualized environments (known to break).
    - generic : any other processor or no CPU-specific optimization. (default)

PCRE (Perl Compatible Regular Expressions) perl正则表述式支持:

    - USE_PCRE=1 to use libpcre, in whatever form is available on your system(shared or static)

    - USE_STATIC_PCRE=1 to use a static version of libpcre even if the dynamic one is available. This will enhance portability.

    - with no option, use your OS libc's standard regex implementation (default).

SSL 支持,需要libz支持, libssl 和 libcrypto 会自动连接 haproxy

    USE_OPENSSL=1


如果操作系统的libc可以使用getaddrinfo()来解析IPv6主机名,旧版可能不支持:

    USE_GETADDRINFO=1

使用zlib压缩

    USE_ZLIB=1

使用libslz压缩, 快单压缩率低
    USE_SLZ=1

配置环境变量

1
2
3
4
5
6
7

cat > /etc/profile.d/haproxy.sh << EOF
export PATH=/usr/local/haproxy/sbin:$PATH

EOF

source /etc/profile.d/haproxy.sh

iptable 防火墙配置

vi /etc/sysconfig/iptables
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 1080 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 1081 -j ACCEPT
-A INPUT -p udp -m state --state NEW -m tcp --dport 514 -j ACCEPT

添加用户

1
2
3
4
5
6
7
8
9
10

groupadd --system --gid 300 g_haproxy

useradd --system --gid 300 --uid 300 --home-dir /var/lib/haproxy --shell /sbin/nologin u_haproxy

mkdir /var/lib/haproxy
chmod 0755 /var/lib/haproxy
chown u_haproxy:g_haproxy /var/lib/haproxy
semanage fcontext -a -t haproxy_var_lib_t "/var/lib/haproxy(/.*)?"
restorecon -RFvv /var/lib/haproxy

配置启动项

## yum 安装haproxy 1.8 的启动文件,安装源IUS

# vi /etc/sysconfig/haproxy

OPTIONS=""

# vi /usr/lib/systemd/system/haproxy.service

[Unit]
Description=HAProxy Load Balancer
After=network.target

[Service]
Environment="CONFIG=/etc/haproxy/haproxy.cfg" "PIDFILE=/run/haproxy.pid"
EnvironmentFile=-/etc/sysconfig/haproxy
ExecStartPre=/usr/sbin/haproxy -f $CONFIG -c -q
ExecStart=/usr/sbin/haproxy -Ws -f $CONFIG -p $PIDFILE $OPTIONS
ExecReload=/usr/sbin/haproxy -f $CONFIG -c -q
ExecReload=/bin/kill -USR2 $MAINPID
KillMode=mixed
Type=notify

[Install]
WantedBy=multi-user.target
## 自定义的启动文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

cat > /usr/lib/systemd/system/haproxy.service << EOF

[Unit]
Description=HAProxy Load Balancer
After=syslog.target network.target

[Service]
Type=forking
##User=root
RuntimeDirectory=haproxy
RuntimeDirectoryMode=0755
Environment="CONFIG_FILE=/etc/haproxy/haproxy.cfg" "PID_FILE=/run/haproxy/haproxy.pid"
EnvironmentFile=-/etc/sysconfig/haproxy
ExecStartPre=/usr/local/haproxy/sbin/haproxy -f \$CONFIG_FILE -c -q
## -W 参数:表示haproxy 采用master-worker 工作模式
ExecStart=/usr/local/haproxy/sbin/haproxy -W -f \$CONFIG_FILE -p \$PID_FILE \$OPTIONS
ExecReload=/usr/local/haproxy/sbin/haproxy -f \$CONFIG_FILE -c -q
ExecReload=/bin/kill -USR2 \$MAINPID
KillMode=mixed
##ExecStop=/usr/bin/kill \`/usr/bin/cat \$PID_FILE\`

[Install]
WantedBy=multi-user.target


EOF



## 配置haproxy 启动文件权限和selinux上下文

chmod 0644 /etc/sysconfig/haproxy /usr/lib/systemd/system/haproxy.service

chown root:root /etc/sysconfig/haproxy /usr/lib/systemd/system/haproxy.service

semanage fcontext -a -t haproxy_unit_file_t /usr/lib/systemd/system/haproxy.service

restorecon -RFvv /usr/lib/systemd/system/haproxy.service
## 对 HAProxy 配置文件的语法做检查:
/usr/local/haproxy/sbin/haproxy -c -f /usr/local/haproxy/conf/haproxy.conf

## 手动开启 HAProxy 的进程:

/usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/conf/haproxy.conf

Haproxy日志记录

在配置前,我们先来了解一下日志的level:local0~local7 16~23保留为本地使用:

    emerg 0 系统不可用;
    alert 1 必须马上采取行动的事件;
    crit 2 关键的事件;
    err 3 错误事件;
    warning 4 警告事件;
    notice 5 普通但重要的事件;
    info 6 有用的信息;
    debug 7 调试信息。

默认 haproxy 是不记录日志的,为了记录日志还需要配置 syslog 模块,在 linux 下是 rsyslogd 服务。

如果要发送日志到远程主机,还需修改远程主机中的/etc/sysconfig/rsyslog中的参数。
安装配置rsyslog
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

## 此步centos 默认已安装,可以跳过
yum -y install rsyslog

## 修改"SYSLOGD_OPTIONS"参数,
## -c 2 :使用兼容模式,默认是 -c 5;
## -r :开启远程日志;
## -m 0 :标记时间戳,单位是分钟,0表示禁用该功能。例如240为每隔240分钟写入一次”–MARK–”信息;
## -x :关闭自动解析对方日志服务器的FQDN信息,这能避免DNS不完整所带来的麻烦;
## -h :默认情况下,syslog不会发送从远端接受过来的消息转发到其他主机,而使用该选项,则把该开关打开,所有接受到的信息都可根据syslog.conf中定义的@主机转发过去。


cp /etc/sysconfig/rsyslog{,.$(date '%F_%T')}

cat > /etc/sysconfig/rsyslog << EOF
SYSLOGD_OPTIONS="-c 2 -r -m 0"

EOF



sed -i "s/#\$ModLoad imudp/\$ModLoad imudp/g" /etc/rsyslog.conf
sed -i "s/#\$UDPServerRun 514/\$UDPServerRun 514/g" /etc/rsyslog.conf

## #文件最末尾的"&~",如果没有此配置,日志除写入指定文件外,会同步写入messages文件;
cat > /etc/rsyslog.d/haproxy.conf << EOF

local2.* /var/log/haproxy.log
&~

EOF

systemctl restart rsyslog.service

haproxy 配置

## 默认安装目录下没有配置文件,只有"doc","sbin","share"三个目录,可手工创建目录及配置文件。

## haproxy的配置文件主要是以下5部分:

## global全局配置、defaults默认配置、监控页面配置、frontend配置、backend配置。


global
    #定义全局日志, 配置在本地, 通过local0 输出, 默认是info级别,可配置两条
    log         127.0.0.1 local2 warning

    chroot      /var/lib/haproxy
    pidfile     /run/haproxy/haproxy.pid

    #设置每haproxy进程的最大并发连接数, 其等同于命令行选项“-n”; “ulimit -n”自动计算的结果参照此参数设定.
    maxconn     4000
    user        u_haproxy
    group       g_haproxy

    #后台运行haproxy
    daemon

    ## 设置启动的haproxy进程数量,一般设置为cpu核数, 只能用于守护进程模式的haproxy;
    ## 默认只启动一个进程
    #nbproc 1

    ## 设置绑定核心,第一个参数表示绑定id,第二个参数指定cpu核心,0开始第一个cpu核心
    ## 后面用bind-process 绑定id,如将CPU核心分开以进行后端处理
    ## frontend access_http
    ##     bind 0.0.0.0:80
    ##     bind-process 1
    ## frontend access_https 
    ##     bind 0.0.0.0:443 ssl crt /etc/yourdomain.pem
    ##     bind-process 2 3 4

    cpu-map 1 0
    cpu-map 2 1
    cpu-map 3 2
    cpu-map 4 3

    ## 调试级别, 一般只在开启单进程时调试, 且生产环境禁用.
    #debug

    ## haproxy启动后不会显示任何相关信息, 这与在命令行启动haproxy时加上参数"-q"相同
    #quiet


    #定义统计信息保存位置
    #stats socket /var/lib/haproxy/stats
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s


    ##===============https相关========================================
    # Default SSL material locations

    ca-base /etc/ssl/certs

    crt-base /etc/ssl/private

    ## Default ciphers to use on SSL-enabled listening sockets.
    ## 参考:https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
    ## 需要处理以下事:
    ## 禁用SSL 2.0(FUBAR)和SSL 3.0 1(POODLE),
    ## 禁用TLS 1.0压缩(CRIME),
    ## 禁用弱密码(DES / 3DES,RC4),更喜欢现代密码(AES),模式(GCM)和协议(TLS 1.2)。
    ## OpenSSL更新为1.0.1c +,以便尽快支持TLS 1.2,GCM和ECDHE
    ## OpenSSL安装进行测试:
    ## openssl ciphers -v 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS'

    ## ssl-default-bind-options <force-sslv3|no-sslv3 no-tls-tickets|force-tlsv10|force-tlsv11|force-tlsv12>
    ssl-default-bind-options force-tlsv12

    ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS

    ssl-default-server-options no-sslv3
    ssl-default-server-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS

    tune.ssl.default-dh-param 2048

    ##============================================================


defaults

    #默认的模式【tcp:4层; http:7层; health:只返回OK】
    mode                    http

    ## 日志类别, httplog
    log                     global

    ## 日志类别, httplog
    option                  httplog

    ## 如果产生了一个空连接,那这个空连接的日志将不会记录.
    option                  dontlognull

    ## 开启http协议中服务器端关闭功能, 每个请求完毕后主动关闭http通道, 使得支持长连接,使得会话可以被重用,使得每一个日志记录都会被记录.
    option http-server-close


    ## 这个参数我是这样理解的:使用该参数,每处理完一个request时,haproxy都会去检查http头中的Connection的值,
    ## 如果该值不是close,haproxy将会将其删除,
    ## 如果该值为空将会添加为:Connection: close。
    ## 使每个客户端和服务器端在完成一次传输后都会主动关闭TCP连接。
    ## 与该参数类似的另外一个参数是"option forceclose",该参数的作用是强制关闭对外的服务通道,
    ## 因为有的服务器端收到Connection: close时,也不会自动关闭TCP连接,
    ## 如果客户端也不关闭,连接就会一直处于打开,直到超时。
    #option httpclose

    #当haproxy负载很高时, 自动结束掉当前队列处理比较久的链接.
    option abortonclose


    ## 当使用了cookie时,haproxy将会将其请求的后端服务器的serverID插入到cookie中,以保证会话的SESSION持久性;
    ## 而此时,如果后端的服务器宕掉了,但是客户端的cookie是不会刷新的,
    ## 如果设置此参数,将会将客户的请求强制定向到另外一个后端server上,以保证服务的正常。

    ## 当与后端服务器的会话失败(服务器故障或其他原因)时, 把会话重新分发到其他健康的服务器上; 当故障服务器恢复时, 会话又被定向到已恢复的服务器上;
    ## 还可以用"retries"关键字来设定在判定会话失败时的尝试连接的次数
    option                  redispatch

    ## 定义连接后端服务器的失败重连次数,连接失败次数超过此值后将会将对应后端服务器标记为不可用
    retries                 3

    ## Insert X-Forwarded-For header
    ## 如果后端服务器需要记录客户端真实ip, 需要在HTTP requests头部中添加"X-Forwarded-For"字段,将客户端IP发送给后端的server;
    ## 但haproxy自身的健康检测机制访问后端服务器时, 不应将记录访问日志,可用except来排除127.0.0.0,即haproxy本身.
    option forwardfor       except 127.0.0.0/8

    #默认http请求超时时间
    timeout http-request    10s

    #默认队列超时时间, 后端服务器在高负载时, 会将haproxy发来的请求放进一个队列中.
    timeout queue           1m

    ## 设置haproxy成功连接到后端服务器的最长等待时间,默认单位是毫秒
    timeout connect         10s

    #客户端与haproxy连接后, 数据传输完毕, 不再有数据传输, 即非活动连接的超时时间.
    timeout client          1m

    #haproxy与后端服务器非活动连接的超时时间.
    timeout server          1m

    #默认新的http请求连接建立的超时时间,时间较短时可以尽快释放出资源,节约资源.
    timeout http-keep-alive 10s

    #心跳检测超时时间
    timeout check           10s

    #最大并发连接数
    maxconn                 3000

    #设置默认的负载均衡方式
    #balance source
    #balnace leastconn





#统计页面配置, frontend和backend的组合体, 监控组的名称可按需自定义
listen admin_stats
    #配置监控运行模式
    mode http

    #配置统计页面访问端口
    bind 0.0.0.0:1080

    #统计页面默认最大连接数
    maxconn 10

    #http日志格式
    option httplog

    #开启统计
    stats enable

    #隐藏统计页面上的haproxy版本信息
    stats hide-version

    #监控页面自动刷新时间
    stats refresh 30s

    #统计页面访问url
    stats uri /stats

    #统计页面密码框提示文本
    stats realm   Haproxy\ Statistics

    #监控页面的用户和密码, 可设置多个用户名
    stats auth    test.admin:test.admin!9595

    #手工启动/禁用后端服务器, 可通过web管理节点
    stats admin if TRUE

    #设置haproxy错误页面,复制源代码目录下错误样本文件(cp ./haproxy-1.8.8/examples/errorfiles/* /usr/local/haproxy)
    errorfile 400 /usr/local/haproxy/errorfiles/400.http
    errorfile 403 /usr/local/haproxy/errorfiles/403.http
    errorfile 408 /usr/local/haproxy/errorfiles/408.http
    errorfile 500 /usr/local/haproxy/errorfiles/500.http
    errorfile 502 /usr/local/haproxy/errorfiles/502.http
    errorfile 503 /usr/local/haproxy/errorfiles/503.http
    errorfile 504 /usr/local/haproxy/errorfiles/504.http






#监控haproxy后端服务器的监控状态
listen site_status
       bind 0.0.0.0:1081 #监听端口
       mode http #http的7层模式
       log 127.0.0.1 local2 err #[err warning info debug]
       monitor-uri /site_status #网站健康检测URL,用来检测HAProxy管理的网站是否可以用,正常返回200,不正常返回503
       acl site_dead nbsrv(php_server) lt 1 #定义网站down时的策略当挂在负载均衡上的指定backend的中有效机器数小于1台时返回true
       acl site_dead nbsrv(html_server) lt 1
       acl site_dead nbsrv(backend_default) lt 1
       monitor fail if site_dead #当满足策略的时候返回503,网上文档说的是500,实际测试为503
       monitor-net 192.168.4.171/32 #来自192.168.4.152的日志信息不会被记录和转发
       monitor-net 192.168.4.172/32

#frontend, 名字自定义
frontend HAproxy_Cluster
    #定义前端监听端口, 建议采用bind *:80的形式,否则做集群高可用的时候有问题,vip切换到其余机器就不能访问.
    bind 0.0.0.0:80

    # 验证服务是否可用
    option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www


    #acl后面是规则名称,当请求的url末尾是以.php结尾时,匹配触发php_web规则,以下两种写法均可.

    #当请求的url末尾是以.css、.jpg、.png、.jpeg、.js、.gif结尾时,匹配并触发static_web规则.
    #acl static_web path_end .gif .png .jpg .css .js .jpeg
    #acl static_web url_reg /*.(css|jpg|png|jpeg|js|gif)$
    #-i为忽略大小写,当被请求的是以www.test.com开头的主机时,匹配并触发dns_name规则.
    acl html_web hdr_beg(host) -i www.haproxytest.com
    #acl html_web hdr_beg(host) 10.11.4.152
    #当客户端的IP是x.x.x.x时,匹配并触发src_ip规则.
    #acl src_ip src x.x.x.x
    #如果匹配acl规则php_web,将请求转交到php_server组处理;如果匹配acl规则html_web,将请求转交到html_server组处理.
    use_backend php_server if php_web
    use_backend html_server if html_web
    #如果以上规则都不匹配时,将请求转交到default_backend组处理.
    default_backend backend_default

#backend后端配置, 配置php_server组与html_server组
backend php_server
    #定义负载均衡方式为roundrobin方式, 即基于权重进行轮询调度的算法, 在服务器性能分布较均匀情况下推荐.
    #另有如下几种负载均衡方式:
    #-- static-rr: 也是基于权重进行轮转调度, 但属于静态方法, 运行时调整后端机组权重不会使用新的权重;
    #-- source: 基于请求源IP进行hash运算匹配后端服务器组;
    #-- leastconn: 不适合会话较短的环境, 如基于http的应用;
    #-- uri: 对整个URI进行hash运算;
    #-- uri_param: 对URI中的参数进行转发;
    #-- hdr(<name>):根据http头进行转发, 无该头部则转为使用roundrobin.
    balance roundrobin
    mode http
    #允许插入serverid到cookie中,serverid后面可定义
    cookie SERVERID
    #心跳检测方式为检测后端服务器index.html文件,还有其他方式
    option httpchk GET /index.html
    #后端服务器定义, maxconn 1024表示该服务器的最大连接数, cookie 1表示serverid为1, weight代表权重(默认1,最大为265,0则表示不参与负载均衡),
    #check inter 1500是检测心跳频率, rise 2是2次正确认为服务器可用, fall 3是3次失败认为服务器不可用.
    server php1 192.168.4.171:80 maxconn 1024 cookie 1 weight 3 check inter 1500 rise 2 fall 3

backend html_server
    balance source
    mode http
    server html1 192.168.4.172:80 maxconn 1024 cookie 1 weight 3 check inter 1500 rise 2 fall 3

backend backend_default
    balance source
    mode http
    server default1 192.168.4.171:80 maxconn 1024 cookie 1 weight 3 check inter 1500 rise 2 fall 3

普通代理负载

frontend  main *:5000
    acl url_static       path_beg       -i /static /images /javascript /stylesheets
    acl url_static       path_end       -i .jpg .gif .png .css .js

    use_backend static          if url_static
    default_backend             app

backend static
    balance     roundrobin
    server      static 127.0.0.1:4331 check

backend app
    balance     roundrobin
    server      app1 127.0.0.1:5001 check
    server      app2 127.0.0.1:5002 check
    server      app3 127.0.0.1:5003 check
    server      app4 127.0.0.1:5004 check

ssl 代理官方示例

global
        maxconn 100

defaults
        mode http
        timeout connect 5s
        timeout client 5s
        timeout server 5s

frontend myfrontend
        # primary cert is /etc/cert/server.pem
        # /etc/cert/certdir/ contains additional certificates for SNI clients
        bind :443 ssl crt /etc/cert/server.pem crt /etc/cert/certdir/
        bind :80
        default_backend mybackend

backend mybackend
        # a http backend
        server s3 10.0.0.3:80
        # a https backend
        server s4 10.0.0.3:443 ssl verify none

适用于redis主从负载

##===============适用于redis主从负载======================================

# Specifies TCP timeout on connect for use by the frontend ft_redis
# Set the max time to wait for a connection attempt to a server to succeed 
# The server and client side expected to acknowledge or send data.

defaults REDIS

    mode tcp
    timeout connect 3s
    timeout server 6s
    timeout client 6s

# Specifies listening socket for accepting client connections using the default 
# REDIS TCP timeout and backend bk_redis TCP health check.

frontend ft_redis
    bind *:6379 name redis
    default_backend bk_redis

# Specifies the backend Redis proxy server TCP health settings 
# Ensure it only forward incoming connections to reach a master.

backend bk_redis
    option      tcp-check
    tcp-check   connect
    tcp-check   send AUTH\ redis\r\n
    tcp-check   send PING\r\n
    tcp-check   expect string +PONG
    tcp-check   send info\ replication\r\n
    tcp-check   expect string role:master
    tcp-check   send QUIT\r\n
    tcp-check   expect string +OK
    server      redis_vm01 200.200.200.221:6381 check port 6381 inter 5s fastinter 2s downinter 5s rise 3 fall 3
    server      redis_vm03 200.200.200.223:6381 check port 6381 inter 5s fastinter 2s downinter 5s rise 3 fall 3

##==========================================================================

redis 主从自动failover 配置

redis sentinel配置

## redis 主从 自动failover 配置

## redis 主从都需要配置masterauth 和 requirepass

## redis 从需要配置slaveof master_ip master_port
## 接下来配置redis sentinel
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

cat > /etc/redis-sentinel.conf << EOF

## 必须绑定ip 或 禁用保护,否则无法实现自动主从切换
# bind 127.0.0.1 192.168.1.1

protected-mode no

port 26379
dir /tmp
# 配置master名、ip、port、需要多少个sentinel才能判断[客观下线]
sentinel monitor mymaster 200.200.200.221 6381 2

#单位毫秒,默认值30000,配置sentinel向master发出ping,最大响应时间、超过则认为主观下线
sentinel down-after-milliseconds mymaster 6000

#配置在进行故障转移时,运行多少个slave进行数据备份同步(越少速度越快)
sentinel parallel-syncs mymaster 1

#单位毫秒,默认值180000,配置当出现failover时下一个sentinel与上一个sentinel对[同一个master监测的时间间
sentinel failover-timeout mymaster 60000

logfile /var/log/redis/sentinel.log
sentinel auth-pass mymaster redis

# sentinel client-reconfig-script mymaster /var/lib/redis/failover.sh

# sentinel notification-script <master-name> <script-path>
# sentinel client-reconfig-script <master-name> <script-path>
# The following arguments are passed to the script:
#
# <master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port>
#
# <state> is currently always "failover"
# <role> is either "leader" or "observer"

## 用于docker nat
# sentinel announce-ip <ip>
# sentinel announce-port <port>


EOF

查看sentinel 状态

# redis-cli  -h 200.200.200.222 -p 26379 info sentinel

# redis-cli  -h 200.200.200.222 -p 26379 info

Sentinel命令

   PING :                              返回 PONG 。
   SENTINEL masters :                  列出所有被监视的主服务器,以及这些主服务器的当前状态;
   SENTINEL slaves <master name> :     列出给定主服务器的所有从服务器,以及这些从服务器的当前状态;
   SENTINEL get-master-addr-by-name <master name> : 返回给定名字的主服务器的 IP 地址和端口号。 如果这个主服务器正在执行故障转移操作, 或者针对这个主服务器的故障转移操作已经完成, 那么这个                     命令返回新的主服务器的 IP 地址和端口号;
   SENTINEL reset <pattern> :          重置所有名字和给定模式 pattern 相匹配的主服务器。 pattern 参数是一个 Glob 风格的模式。 重置操作清楚主服务器目前的所有状态, 包括正在执行中的故障转移, 并移除目前已经发现和关联的, 主服务器的所有从服务器和 Sentinel ;
   SENTINEL failover <master name> :   当主服务器失效时, 在不询问其他 Sentinel 意见的情况下, 强制开始一次自动故障迁移。
   SENTINEL ckquorum <master name>      检查当前的Sentinel配置对于主节点的故障转移是否能达到仲裁人数,并且大多数是需要的来授权故障转移。这个命令应该在监控系统中使用来检查一个Sentinel部署是否正常。
   SENTINEL flushconfig                 强制Sentinel重新写入它的配置到磁盘上,包括当前Sentinel状态。


运行配置命令:

SENTINEL MONITOR <name> <ip> <port> <quorum>    这个命令告诉Sentinel开始监控一个指定名称、IP、端口号、quorum的主节点,它和sentinel.conf配置文件中的sentinel monitor配置指令是完全相同的,不同的是这里不能使用主机名作为IP,需要提供一个IPV4或IPV6地址。
SENTINEL REMOVE <name>                          用来移除指定的主节点:主节点不再被监控,并且将被从Sentinel的内部状态中被完全移除,所以不会被SENTINEL masters列出。
SENTINEL SET <name> <option> <value> SET        命令和Reids的CONFIG SET指令非常相似,被用来改变一个指定主节点的配置参数。多个选项-值可以被指定。所有通过sentinel.conf配置的参数可以使用SET命令重新配置。


Sentinel命令

127.0.0.1:26379> sentinel masters
127.0.0.1:26379> sentinel slaves mymaster
127.0.0.1:26379> SENTINEL get-master-addr-by-name mymaster
127.0.0.1:26379> SENTINEL reset mymaster
127.0.0.1:26379> SENTINEL failover mymaster
127.0.0.1:26379> SENTINEL flushconfig

SENTINEL SET mymaster down-after-milliseconds 1000


运行时的配置指令

SENTINEL MONITOR 新增监控的master,不能使用hostname代替真实的ip
SENTINEL REMOVE 不再监控指定master
`SENTINEL SET

哨兵的添加与删除

    添加哨兵很简单,只要监控master就可以被大家发现。删除哨兵则需要一下步骤:

    杀死该哨兵进程
    发送SENTINEL RESET *给其他哨兵
    检查所有哨兵,发送指令SENTINEL master给所有哨兵来查看活跃的哨兵数量

利用redis-sentinel自带的参数进行VIP的配置

# 设置环境

# redis 绑定IP必须使用0.0.0.0 
sed -i "s|bind 200.200.200.223|bind 0.0.0.0|g" /etc/redis2.conf 

# redis 配置,如果有三个redis服务器和三个 redis-sentinel,最好添加下面的配置,以防数据不一致
min-slaves-to-write 1
min-slaves-max-lag 10

# 脚本执行权限
vi /var/lib/redis/failover.sh
chmod 0550 /var/lib/redis/failover.sh
chown redis: /var/lib/redis/failover.sh

# redis 用户的权限
echo -e 'redis\tALL=(ALL)\tNOPASSWD:/sbin/ip,NOPASSWD:/sbin/arping' > /etc/sudoers.d/redis
##echo -e 'Defaults!/sbin/ip !requiretty' >> /etc/sudoers.d/redis
##echo -e 'Defaults!/sbin/arping !requiretty' >> /etc/sudoers.d/redis
## sed -i "s|Defaults.*requiretty|#Defaults\trequiretty|" /etc/sudoers

chmod 440 /etc/sudoers.d/redis


## <master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port>
# sentinel client-reconfig-script mymaster /var/lib/redis/failover.sh
#!/bin/bash 这一行开头不能有空格,否则无法执行下面的命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
vi /var/lib/redis/failover.sh
#!/bin/bash

MASTER_IP=${6}
##MY_IP='200.200.200.221' # 每个Server本身的IP

MY_IP=$(ip addr show | grep inet |grep -v 127.0.0.1| awk '{print $2}' | awk -F/ '{print $1}')

VIP='200.200.200.240' # VIP
NETMASK='24' # Netmask
INTERFACE='ens33' # 接口

## 指定MY_IP
##if [ ${MASTER_IP} = ${MY_IP} ]; then

## 未指定MY_IP
##if [[ ${MY_IP} =~ ${MASTER_IP} ]]; then
if echo ${MY_IP} | grep -wq ${MASTER_IP}; then
sudo /sbin/ip addr add ${VIP}/${NETMASK} dev ${INTERFACE}
sudo /sbin/arping -q -c 3 -A ${VIP} -I ${INTERFACE}
exit 0
else
sudo /sbin/ip addr del ${VIP}/${NETMASK} dev ${INTERFACE}
exit 0
fi
exit 1

手动切换slave到master

## 登陆redis slave,输入

> slaveof NO ONE

或者

    $ redis-cli -a password -p 6379 -h 200.200.200.223 slave no one

手动切换master到slave

    $ redis-cli -a password -p 6379 -h 200.200.200.223 slaveof 200.200.200.223 6379


单线程SET/GET测试

    $ redis-benchmark -p xxx -t set,get -r 3000 -n 1000000 -d xxx 

单线程PIPELINE SET/GET测试

    $ redis-benchmark -p xxx -t set,get -r 3000 -n 5000000 -P 20 -d xxx

参考:

sudo:

    1)Defaults    requiretty,修改为 #Defaults    requiretty,表示不需要控制终端。

    2)Defaults    requiretty,修改为 Defaults:nobody !requiretty,表示仅 nobody 用户不需要控制终端。

    3)如果修改为 Defaults:%nobody !requiretty,表示仅 nobody 组不需要控制终端。

    4)Defaults!/path/to/program !requiretty 表示/path/to/program 不需要控制终端。

    5) 如果名带有参数必须使用别名
    Cmnd_Alias MYPROGRAM = /path/to/program --option
    artbristol ALL = (root) /path/to/program
    artbristol ALL = (root) NOPASSWD: MYPROGRAM
    Defaults!MYPROGRAM !requiretty

    6) 省略所有命令的密码
    username ALL=(ALL) NOPASSWD: ALL

    参考:
    https://www.sudo.ws/man/1.8.15/sudoers.man.html


arping:

    二.命令格式

    arping  [-AbDfhqUV] [-c count] [-w deadline] [-s source] [-I interface] destination

    三.常用参数
    复制代码

        -A            #和U参数作用相同,不过发送的是ARP应答包
        -b            #保持广播状态(收到arp应答之后会切换成单一传播模式)
        -c count      #发送指定数量的ARP请求包
        -D            #冲突检测模式,如果返回为空,则代表该ip没有被占用
        -f            #当收到确认主机存活的第一个数据包时,停止发送
        -I interface  #指定发送ARP数据包使用的网卡设备
        -h            #打印帮助并退出
        -q            #不显示警告信息
        -s source     #设置源ip地址,DAD模式下为0.0.0.0,主动模式下为自己设定的ip地址,不设置则为本机实际ip地址
        -U            #主动发送ARP请求来更新其他主机的ARP缓存
        -V            #打印版本信息并退出
        -w deadline   #设置超时时间,    

ssl终结配置

支持 https:

frontend name(name 这里比如:http_server 和 main *:5000 等)
        bind 0.0.0.0:80
        bind 0.0.0.0:443 ssl crt /etc/haproxy/keys/www.test.com.pem

只需要在 frontend 这里添加一行配置(监听 443 端口,再告诉 HAProxy 存放 CA 证书的位置)即可。

www.test.com.pem 这个文件应该需要如下形式,即把 key 也要附上:

-----BEGIN CERTIFICATE-----
BAQDAgEGM798a1UdEwEB/wQIMAYBAf8CAQAQMKYIKwYBBQUHAQEEJzAlMCMGCCsG

...

k3YtCAbvmq==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----  
IGZvciBhdXRob3JpemVkIHVz9zBvbmx5MS4wLAYDVSSDEyVFbnRydXN0IMAlcnRp 

...

QnLcB= 
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
SnXgfbEA3wLWqbjZiGkReyuxlZs+peS644u6+vnxTbmVHH+3t3rmubDK7nEACI81

...

cckLx6AQUD/7oUbcB9wKG5sy9EhYrCkg9wYYGyPlgUuRdLZny0I0Bw==
-----END RSA PRIVATE KEY-----

支持多个 https:

frontend name(name 这里比如:http_server 和 main *:5000 等)
        bind :80
        bind :443 ssl crt /etc/haproxy/keys/www.test.com.pem crt /etc/haproxy/keys/admin.test.com.pem crt /etc/haproxy/keys/passport.abc.com.pem

只需要连续不断地添加证书即可,HAProxy 会自动地根据不同的域名去使用相关的证书,不需要额外配置。

网上说 https 的配置要这么配:

frontend name(name 这里比如:http_server 和 main *:5000 等)
        bind :80
        bind :443 ssl crt /etc/haproxy/keys/www.test.com.pem crt /etc/haproxy/keys/admin.test.com.pem crt /etc/haproxy/keys/passport.abc.com.pem

        acl admintest_com hdr_dom(host) -i admin.test.com
        use_backend admin_test_com if admintest_com { ssl_fc_sni admin.test.com } 

        acl passportabc_com hdr_dom(host) -i passport.abc.com
        use_backend pasport_abc_com if passport_abc_com { ssl_fc_sni passport.abc.com }

...

即在 use_backend 的后面还要添加 { ssl_fc_sni admin.test.com } ,表示 “ 指定 ” (或者说是强制)使用某个证书。其实这么做的话这个域名就没法通过 80 端口来访问了,只能通过 443 端口来访问。要想 443 端口和 80 端口都能同时访问还需要这么做:

frontend name(name 这里比如:http_server 和 main *:5000 等)
        bind :80
        bind :443 ssl crt /etc/haproxy/keys/www.test.com.pem crt /etc/haproxy/keys/admin.test.com.pem crt /etc/haproxy/keys/passport.abc.com.pem

        acl admintest_com hdr_dom(host) -i admin.test.com
        use_backend admin_test_com if admintest_com

        acl admintest_com hdr_dom(host) -i admin.test.com
        use_backend admin_test_com if admintest_com { ssl_fc_sni admin.test.com }

        acl passportabc_com hdr_dom(host) -i passport.abc.com
        use_backend pasport_abc_com if passport_abc_com

        acl passportabc_com hdr_dom(host) -i passport.abc.com
        use_backend pasport_abc_com if passport_abc_com { ssl_fc_sni passport.abc.com }

...

即再添加一个不 “ 指定 ” 证书的配置。

这么做我觉得完全没有必要,只要添加 bind :443 ssl crt /etc/haproxy/keys/www.test.com.pem … 这一行配置就行,剩下的让 HAProxy 自动地根据不同的域名去使用相关的证书即可。

http 跳转 https:

#对以下站点进行 https 跳转

acl ssl hdr_reg(host) -i ^(www.test.com|admin.test.com|passport.abc.com)$
redirect scheme https code 301 if !{ ssl_fc } ssl

证书配置的安全性改进:

bind 0.0.0.0:443 ssl crt 1.pem no-sslv3 ciphers AES:ALL:!aNULL:!eNULL:-RC4:-EXPORT:-DES crt 2.pem no-sslv3 ciphers AES:ALL:!aNULL:!eNULL:-RC4:-EXPORT:-DES